package com.audaque.springboot.foshanupload.authcore.model.currentUser;

import com.alibaba.ttl.TransmittableThreadLocal;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Set;

/**
 * @author zgb
 * @desc   执行任务的线程是被线程池管理，可以被复用（可以称为池化复用）。那复用了之后，如果还是依赖于父线程的 context，自然是有问题的，因为我们想要的效果是执行线程获取调用线程的 context，这时候就是TransmittableThreadLocal出场了。
场景：就是父子线程或者不同线程需要共用一些变量。举个例子：之前在肥朝哥群里，肥大一直叼胃口，因为全链路日志是自研的嘛，没有sleuth等等框架的支持，所以像MDC这些全局变量，在多线程里头就失效了。
 * @date 2022-05-09 10:30:59
 */
@Schema(description = "当前用户信息")
@Data
@Slf4j
@NoArgsConstructor
@AllArgsConstructor

public class TransmittableThreadLocalCurrentUser implements Serializable {
    private static final long serialVersionUID = -1242493306307174690L;
    private static final TransmittableThreadLocal<TransmittableThreadLocalCurrentUser> THREAD_LOCAL = new TransmittableThreadLocal<>();
    //放在上下文
    private String id;
    private String tenantId;
    private String username;
    private String accessToken;
    private String sessionId;
    private Set<String> roleIds;

    //不放在上下文 ，只作为请求参数
    private String password;
    private LocalDateTime passwordExpireTime;
    private String name;
    private String phone;
    private String idCardNumber;
    private String loginIp;
    private Boolean enableYn;



    public static void setCurrentUser(TransmittableThreadLocalCurrentUser user) {
        THREAD_LOCAL.set(user);
    }

    public static TransmittableThreadLocalCurrentUser getCurrentUser() {
        return THREAD_LOCAL.get();
    }


    public static void remove(){
        THREAD_LOCAL.remove();
        TransmittableThreadLocalCurrentUser transmittableThreadLocalCurrentUser = THREAD_LOCAL.get();
        log.info("remove transmittableThreadLocalCurrentUser:{}",transmittableThreadLocalCurrentUser);
    }
}
